/**
 * 
 */
package com.planner.core.dao;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.Query;

import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;

import com.planner.core.service.core.EMFService;
import com.planner.core.vo.GraphNode;

/**
 * @author Sangharsh
 *
 */
public enum NodeDAOImpl implements NodeDAO<GraphNode>{
	INSTANCE;
	
	private static final Log LOG = LogFactory.getLog(NodeDAOImpl.class);
	
	public List<GraphNode> getAllNodes() {
		EntityManager em = EMFService.get().createEntityManager();
		// Read the existing entries
		Query q = em.createQuery("select grno from GraphNode grno");
		List<GraphNode> nodes = getResultList(q);
		return nodes;
	}
	public void add(GraphNode node) {
		LOG.info("Adding Node"+node);
		synchronized (this) {
			EntityManager em = EMFService.get().createEntityManager();
			em.persist(node);
			em.close();
		}
	}
	public void addAll(List<GraphNode> nodes) {
		LOG.info("Adding Node");
		synchronized (this) {
			EntityManager em = EMFService.get().createEntityManager();
			for(GraphNode node : nodes){
				LOG.info("Persisting Node:"+node);
				em.persist(node);
			}
			em.close();
		}
	}

	public GraphNode getNode(long id) throws NodeNotFoundException{
		LOG.info("GetNode for id "+id);
		EntityManager em = EMFService.get().createEntityManager();
		Query q = em.createQuery("select grno from GraphNode grno where grno.id = :id");
		q.setParameter("id", id);
		List<GraphNode> nodes = getResultList(q);
		if(nodes==null || nodes.isEmpty()){
			throw new NodeNotFoundException("Node with Id "+id +" not found");
		}
		return nodes.get(0);
	}
	
	public GraphNode getNode(String code) throws NodeNotFoundException{
		EntityManager em = EMFService.get().createEntityManager();
		Query q = em.createQuery("select grno from GraphNode grno where grno.code = :code");
		q.setParameter("code", code);
		List<GraphNode> nodes = getResultList(q);
		if(nodes==null || nodes.isEmpty()){
			throw new NodeNotFoundException("Node with Code "+code +" not found");
		}
		return nodes.get(0);
	}
	
	public void updateNode(GraphNode node) {
		synchronized (this) {
			EntityManager em = EMFService.get().createEntityManager();
			try{
			    em.getTransaction().begin();
			    GraphNode dbNode = em.find(GraphNode.class, node.getId());
			    dbNode.setCode(node.getCode()); 
			    dbNode.setName(node.getName());
			    dbNode.setDescription(node.getDescription());
			    em.getTransaction().commit();
			  } finally {
			    em.close();
			  }
		}
	}

	public void deleteNode(long id) {
		EntityManager em = EMFService.get().createEntityManager();
		try {
			GraphNode todo = em.find(GraphNode.class, id);
			em.remove(todo);
		} finally {
			em.close();
		}
	}
	@SuppressWarnings("unchecked")
	private <T> List<T> getResultList(Query q){
		return (List<T>)q.getResultList();
	}
}
